feat(errors): implement StellarError (#35) - #54
Conversation
Implements issue ShadeProtocol#35. StellarError wraps the underlying stellar_sdk exception so callers keep the raw error while catching a single SDK type, and exposes the Horizon result codes for programmatic handling. - stellar_result_code carries the transaction-level code, falling back to the first failing operation code when Horizon reports no transaction one - operation_result_codes keeps the per-operation codes in Horizon's order, with failed_operation_code skipping op_success entries - original_error holds the raw stellar_sdk exception; Horizon status and response body are attached where available - Messages describe the specific failure (missing trustline, underfunded account, ...) via result-code tables, falling back to the raw code so an unrecognised code still reaches the caller - wrap_stellar_errors() context manager for the Stellar integration layer to catch and re-raise stellar_sdk failures Malformed Horizon payloads degrade to "no result codes" rather than raising while building the exception.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe PR adds Horizon result-code parsing, a ChangesStellar error handling
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Horizon
participant stellar_sdk
participant wrap_stellar_errors
participant StellarError
Horizon-->>stellar_sdk: Return error body and result codes
stellar_sdk-->>wrap_stellar_errors: Raise SdkError
wrap_stellar_errors->>StellarError: Convert via from_exception
StellarError-->>wrap_stellar_errors: Return structured exception
wrap_stellar_errors-->>stellar_sdk: Raise StellarError with cause
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
codebestia
left a comment
There was a problem hiding this comment.
LGTM!
Thank you for your contribution
Description
Implements
StellarError, the last exception in the SDK's typed hierarchy. It wraps the underlyingstellar_sdkexception so callers keep access to the raw error while still catching a single SDK type, and exposes Horizon's result codes for programmatic handling.StellarError(ShadeError)insrc/shade/errors.py:stellar_result_codetx_failed,tx_insufficient_fee, …). Falls back to the first failing operation code when Horizon reports no transaction code.operation_result_codesop_successentries included.failed_operation_codeop_successcode, so callers can branch onop_no_trust/op_underfundedwithout walking the list.original_errorstellar_sdkexception.status_code/response_bodyResult codes are read from
extras.result_codes, matchingstellar_sdk13.2.1'sBaseHorizonError. Messages are built from two lookup tables (transaction + operation codes), preferring the operation-level failure since that is what actually went wrong:Unrecognised codes are passed through raw rather than swallowed. Non-Horizon failures fall back to
account_id(forAccountNotFoundException), then Horizon'stitle/detail, thenstr(exc).wrap_stellar_errors()— a context manager covering the issue's third step. The Stellar integration layer wraps its Horizon/Soroban calls with it so callers only ever have to catchShadeError:Both are exported from the top-level
shadepackage.Fixes #35
Type of change
How Has This Been Tested?
27 new tests in
tests/test_stellar_error.py, built against realstellar_sdkexception instances rather than mocks.failed_operation_codeskippingop_success, Horizon status/body capture,__str__formatting, fallback to the operation code when no transaction code is presentop_no_trust,op_src_no_trust), underfunded accounts, operation code taking precedence over the transaction code, unrecognised codes passed through raw, explicit message override,title/detailfallback,AccountNotFoundException, non-HorizonSdkErrororiginal_errorexposes the raw exception and isNonewhen constructed directlyresult_codes, non-listoperations, non-string entries — all degrade to "no result codes" instead of raising while building the exceptionwrap_stellar_errors: converts and chains (__cause__), honours the message override, lets non-stellar_sdkexceptions through untouched, transparent on successFull suite: 277 passed, 3 skipped, no regressions. Both CI flake8 gates clean (
--select=E9,F63,F7,F82and--max-complexity=10 --max-line-length=127).Checklist:
Note on scope
The issue's third proposed step says to catch
stellar_sdkexceptions "in the Stellar integration layer". That layer (shade/stellar/, FEATURES.md §6) does not exist yet and has no issues filed for it. Rather than build it here, this PR delivers the catching mechanism aswrap_stellar_errors()so that work can simply apply it at each Horizon/Soroban call site.StellarErroritself is complete and all three acceptance criteria are met.Summary by CodeRabbit
StellarErrorexceptions.